#include <cstring>
#include <pcre.h>

#include "gt_file.h"
#include "gt_line.h"
#include "gt_search_util.h"
// ok
static int match_blank_line(result_t *result, const char *output) {
  size_t line_length = strlen(output);
  if (line_length == 0)
    return 1;

  const char *match = apply_regex(output, "^(--)$");

  if (!match)
    return 0;

  result->entries = create_blank_line(result);
  pcre_free_substring(match);

  return 1;
}
// ok
static int match_file(result_t *result, const char *output) {
  const char *match = apply_regex(output, "(?<=(\\[1;32m))[^\\033]*");
  if (!match)
    return 0;

  if (!validate_file(match))
    return 1;

  result->entries = create_file(result, (char *)match);
  pcre_free_substring(match);

  return 1;
}
// ok
static int match_line(result_t *result, const char *output) {
  const char *match = apply_regex(output, "(?<=(\\[1;33m))[^\\033]*");
  if (!match)
    return 0;

  size_t line_number = atoi(match);
  pcre_free_substring(match);

  if (line_number == 0)
    return 0;

  match = apply_regex(output, "(?<=(\\[K[-])).*$");
  if (match) {
    result->entries =
        create_unselectable_line(result, (char *)match, line_number);
    pcre_free_substring(match);
    return 1;
  }

  range_t highlight = {0, 0};
  size_t line_length = 1024;
  char *line = (char *)calloc(line_length, sizeof(*line));

  match = apply_regex(output, "(?<=(\\[K[:]))[^\\033]*");
  if (!match)
    return 0;

  resize_string(&line, &line_length, strlen(match));
  strcat(line, match);
  pcre_free_substring(match);

  match = apply_regex(output, "(?<=(\\[30;43m))[^\\033]*");
  if (!match)
    return 0;

  highlight.begin = strlen(line);
  highlight.end = highlight.begin + strlen(match);

  resize_string(&line, &line_length, strlen(match));
  strcat(line, match);
  pcre_free_substring(match);

  match = apply_regex(output, "(?<=(\\[K))[^\\033]*$");
  if (!match) {
    return 0;
  }

  resize_string(&line, &line_length, strlen(match));
  strcat(line, match);
  pcre_free_substring(match);

  result->entries = create_line(result, line, line_number, highlight);

  return 1;
}
// ok
void do_ag_search(search_t *search) {
  char default_args[] = "-H --color ";
  external_parser_t ag = {default_args, match_file, match_line,
                          match_blank_line};
  popen_search(search, &ag);
}